from .Board import Board
from .Chess import ChessBase
from .Pos import Pos
from typing import List, Tuple, Callable, NoReturn
import copy
from .History import HistoryEntry, TakebackEvent


class Game:
    def __init__(self, history_handler: "Callable[[HistoryEntry],NoReturn]" | None = None):
        self.player = [0, 0, 0, 0]  # 玩家 SessionId
        self.board = Board()
        self.dead = [0, 0, 0, 0]  # 被哪个玩家击败的
        self.history: "List[HistoryEntry]" = []
        self.history_callback = history_handler
        self.last_board: "Board" = None
        self.round = 0

    def commit_history(self, his: HistoryEntry):
        self.history_callback(his)
        self.history.append(his)

    def current_player(self):
        return self.round % 3+1

    def take_back(self):
        if self.last_board is not None:
            self.board = self.last_board
            self.last_board = None
            self.round = self.round-1
            self.commit_history(TakebackEvent(self.current_player()))
            return True
        return False

    def use_skill(self, pos: Pos, **kwargs):
        lstb = copy.copy(self.board)
        res = self.board.try_skill(self.current_player(), pos, kwargs)
        if res == False:
            return False
        self.round = self.round+1
        self.last_board = lstb
        return True

    def try_move(self, pos: Pos, nxt: Pos):
        lstb = copy.copy(self.board)
        res = self.board.try_move(self.current_player(), pos, nxt)
        if res == False:
            return False
        self.round = self.round+1
        self.last_board = lstb
        return True

    def is_end(self):
        if self.dead.count(0) >= 2:
            return 0
        return 1 if self.dead[1] == 0 else 2 if self.dead[2] == 0 else 3
